home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-10-30 | 72.5 KB | 1,717 lines |
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- NNNNAAAAMMMMEEEE
- ttttccccllllMMMMoooottttiiiiffff - the binding of tcl to the Motif widget set.
-
-
- IIIInnnnttttrrrroooodddduuuuccccttttiiiioooonnnn
- This is a binding of the Tcl language to the Motif widgets. Tcl is an
- interpreted language originally intended for use as a command language
- for other applications. It has been used for that, but has also become
- useful as a language in its own right.
-
- Tcl has been extended by a set of widgets called Tk. The Tk widgets are
- not based on the Xt Intrinsics, but are built above Xlib. They allow an
- easy way of writing X Window applications.
-
- The standard set of widgets in the X world is now the Motif set. This
- forms a large set of widgets, and these have been through a large amount
- of development over the last five years. Use of this set is sometimes a
- requirement by busineses, and other widget sets try to conform to them in
- appearance and behaviour.
-
- This system allows the programmer to use the Motif widgets instead of the
- Tk widgets from Tcl programs. This increases programmer choices, and
- allows comparison of the features of both Tcl and the Tk/Motif style of
- widget programming. The binding gives the full set of Motif widgets,
- accessible through the simple interpreted Tcl language.
-
-
- AAAAcccckkkknnnnoooowwwwlllleeeeddddggggmmmmeeeennnnttttssss
- This system is based on Tk for the style of widget programming. This was
- because it provides a good model, but it also allows the Tcl programmer
- to move relatively easily between Tk and Motif programming. An
- alternative style of binding to Motif is used in the WKSH system, which
- performs a similar sort of role for the Korn Shell. The WKSH is much
- closer to the C API for Xt than is Tk. An intermediate style is provided
- by the Wafe binding of Xt-based widgets to tcl.
-
- The documentation is incomplete (and is likely to be for a very long
- time). Consequently the programmer will probably need to refer to the
- Motif Programers Reference Manual. The system has been designed so that
- it is relatively easy to translate the C-based information in this manual
- into the corresponding Tcl information. This has been aided by the
- consistency with which Motif has been implemented in certain areas.
-
-
- RRRRuuuunnnnnnnniiiinnnngggg TTTTccccllll////MMMMoooottttiiiiffff pppprrrrooooggggrrrraaaammmmssss
- Tcl/Motif programs may be run by the `moat' (MOtif And Tcl) interpreter.
- When called with no arguments it reads Tcl commands from standard input.
- When called by
-
- moat file-name
-
- it reads Tcl commands from `file-name' and executes them. This is the
-
-
-
- PPPPaaaaggggeeee 1111
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- same as any other extension to ``tclsh''.
-
- The standard Xt command line options may appear after the file-name, as
- in
-
- moat file-name -width 200 -height 100
-
- Depending on your shell interpreter, you will probably be able to run
- Tcl/Motif programs as standalone programs. If your moat interpreter is
- installed in say `/usr/local/bin/moat', make this the first line of your
- executable program:
-
- #!/usr/local/bin/moat
-
-
- TTTThhhheeee MMMMoooottttiiiiffff wwwwoooorrrrlllldddd
- In earlier versions than 0.8, a specialised interpreter was used, much
- like Tk's ``wish''. To conform to the new extension methods of tcl7.0,
- this was changed. Part of the result of this is that the Xt world has to
- be explicitly brought into existence. This also allows the class and
- fallback resources to be set, and leaves hooks for things like setting
- the application icon to be added later to this binding.
-
- The three world manipulation functions added are
-
- xtAppInitialize
- . realizeWidget
- . mainLoop
-
- xtAppInitialize may take parameters of -class, -fallback_resources and
- -options. If the class option is omitted, the binding will deduce a class
- by capitalising the first letter of the application name, and - if it was
- an `x' - also capitalising the second letter. The -fallback_resources
- may be used to set resources in case there is no application defaults
- file or user file setting them. The -options may be used to set
- additional application resources for later retrieval by the root widget
- method getAppResources.
-
- A typical tclMotif program has the structure
-
- # tcl function definitions
- # ...
-
- xtAppInitialize -class MyClass
-
- # widget creation commands
- # ...
-
- . realizeWidget
- . mainLoop
-
-
-
-
-
- PPPPaaaaggggeeee 2222
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- WWWWiiiiddddggggeeeetttt nnnnaaaammmmiiiinnnngggg
- Widgets are visual objects that exist on the screen. They are organised
- as a hierarchy, with the application itself forming the root of this
- hierarchy. The naming of objects within this hierarchy is similar to the
- ``absolute path names'' of Unix files with a `.' replacing the `/' of
- Unix. The application itself is known as `.'. A Form in the application
- may be known as `.form1'. A Label in this form may be `.form1.okLabel',
- and so on. Note that Xt requires that `.' can only have one child
- (except for dialogs). This naming convention is the same as in Tk.
-
-
- WWWWiiiiddddggggeeeetttt ccccrrrreeeeaaaattttiiiioooonnnn
- Widgets belong to classes, such as Label, PushButton or List. For each
- class there is a creation command which takes the pathName of the object
- as first argument with optional further arguments:
-
- xmForm .form1
- xmLabel .form1.okLabel
- xmLabel .form1.cancelLabel \
- -labelString "Get rid of me"
-
- creates a Form `form1' as child of `.', and two Labels `okLabel' and
- `cancelLabel' as children of `form1'. The `cancelLabel' has additional
- arguments that set the labelString to "Get rid of me". Note that the
- continuation character `\' may be used to spread a line over several
- lines.
-
- The set of classes generally mirrors the Motif set. Some widgets in
- Motif and Xt are not accessible from this binding because they are
- intended for use in inheritance only, such as Core and Primitive. The
- types of widgets that can be created using this include the primitive
- widgets:
-
- xmArrowButton - a simple arrow,
- xmDrawnButton - a button with graphics in it
- xmCascadeButton - for use in menus
- xmToggleButton - for on/off boxes
- xmLabel - a fixed piece of text
- xmText - a text editor
- xmTextField - a one line text editor
- xmSeparator - for simple lines between objects
- xmList - a list selector
- xmScrollBar - a horizontal or vertical scrolling bar
-
- and the Manager widgets:
-
- xmBulletinBoard - simple geometry management
- xmRowColumn - regular geometry management
- xmPanedWindow - multiple panes separated by sashes
- xmFrame - a 3-D border
- xmScale - a slider on a scale
- xmScrolledWindow - for displaying a clip view over an area
-
-
-
- PPPPaaaaggggeeee 3333
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- xmMainWindow - contains a menu bar and the main application windows
- xmForm - for irregular geometry arrangements
- xmMessageBox - message display area
- xmCommand - a command entry area with a history list
- xmFileSelectionBox - selection of a file from a list
-
- Motif has two special commands for creating a ScrolledList and a
- ScrolledText. These commands actually create a pair of widgets: a List
- or Text inside a ScrolledWindow. To create such widgets is similar to the
- C binding: the List (or Text) widget name is given. If the parent
- ScrolledWindow is required then you have to call the ``parent'' method on
- the List or Text widget.
-
- xmForm .form1
- xmScrolledList .form1.list2
- [.form1.list2 parent] setValues -attachTop attach_form
-
- Motif also has convenience functions that create dialogs. These don't
- create ordinary widgets, but Motif pretends that they do. TclMotif
- follows this, and allows you to use commands such as
-
- xmQuestionDialog .askMe
-
- to create such dialogs. When you have to destroy such widgets, destroy
- the parent:
-
- [.askMe parent] destroy
-
- This set of dialogs includes:
-
-
- xmBulletinBoardDialog - a dialog with arbitrary contents, based on
- bulletinBoard
-
- xmFileSelectionDialog - a dialog based on fileSelectionBox
-
- xmFormDialog - a dialog based on form
-
- xmInformationDialog - a dialog displaying information
-
- xmMessageDialog - a dialog showing a message
-
- xmPromptDialog - a dialog with a prompt area
-
- xmQuestionDialog - a dialog asking a question
-
- xmSelectionBoxDialog - a dialog based on selectionBox
-
- xmWarningDialog - a dialog showing a warning message
-
-
-
-
-
-
- PPPPaaaaggggeeee 4444
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- xmWorkingDialog - a dialog showing a busy working message
-
- For example, consider a rowColumn containing two labels and a pushButton,
- where the rowColumn is inside a mainWindow:
-
- xmMainWindow .main
- xmRowColumn .main.rowcol
- xmLabel .main.rowcol.label1
- xmLabel .main.rowcol.label2
- xmPushButton .main.rowcol.btn
-
- Not all objects used in the OSF C library are supported: gadgets are not
- supported by TclMotif, nor are the ``simple'' menu functions. These are
- design decisions: I don't like gadgets because they place extra
- processing code and complexity on the client-side Motif library, the need
- for which has been largely removed by improvements in X servers; I don't
- like the simple menu functions very much either because they are yet
- another attempt to fix up a complex system to which lots of people
- already have their own solutions, and it is not clear that this is a
- ``better'' one. I doubt if reversal of these would cause too many
- problems, but I don't feel like investigating them yet.
-
-
-
- MMMMaaaannnnaaaaggggiiiinnnngggg wwwwiiiiddddggggeeeettttssss
- Before a widget can be displayed, it must be brought under the geometry
- control of its parent (similar to placing a Tk widget). This can be done
- by the ``manageChild'' method of each widget, but also by an optional
- third command to each widget creation function, similar to the
- XtCreateManagedWidget functions. For example,
-
- xmLabel .l1 managed
- xmLabel .l2
- .l2 manageChild
-
-
- DDDDooooccccuuuummmmeeeennnnttttaaaattttiiiioooonnnn
- The widgets described above not only look and act the same as the Motif
- widgets, they _a_r_e the Motif widgets. So descriptions of them in any Motif
- book or reference apply. In the Motif Programmers Reference these widgets
- are described under the same names, with the initial `x' capitalised as
- in XmPushButton. The creation functions are prefixed by ``XmCreate'' as
- in XmCreatePushButton.
-
- The TclMotif documentation is at present incomplete. There should be a
- man page for each widget, under the name of the widget prefixed by ``Tm''
- as in TmPushButton.
-
- In addition, there are additional manual pages. The entry for ``moat''
- describes the interpreter that will generally be used for TclMotif. The
- entry for TmRoot describes the commands available for the root widget
- ``.''. Such commands usually apply to the Xt application context.
-
-
-
- PPPPaaaaggggeeee 5555
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- WWWWiiiiddddggggeeeetttt ccccoooommmmmmmmaaaannnnddddssss
- Creating a widget actually creates a Tcl command known by its pathName.
- This command may be executed with at least one parameter to either change
- the behavior of the object or the value of its components, or to get
- information about the object. The parameter acts like a ``method'' to
- the object, and specifies an action that it should perform. The
- parameters that are recognised by every object include:
-
-
- unmanageChild - remove the object from its parents geometry
- management, which makes it disappear from the display
-
- manageChild - bring it back under geometry management and make it
- appear again
-
- mapWidget - remain under geometry management, but make it disappear
-
- unmapWidget - make it reappear
-
- realizeWidget - create windows for the widget and its children
- (usually used only by ``.'')
-
- getValues - obtain properties of the widget
-
- setValues - set properties of the widget
-
- parent - return the parent of the widget
-
- destroyWidget - destroy the widget and all its children
-
- setSensitive - change the sensitivity of the widget to responses to
- input
-
- callActionProc - call an action procedure (usually used in
- regression testing)
-
- dragStart - used in drag and drop
-
- dropSiteRegister - used in drag and drop
-
- getGC - return a graphics context (used for drawing in DrawingArea
- and DrawnButton)
-
- resources - return a list of all resources. Each resource is a list
- of the resource name as used in setValues/getValues, the
- resource name as known internally to Motif, the resource class,
- the resource type as known to Motif and the value of the
- resource. In cases where this value does not make sense (eg a
- bitmap), a null string is returned.
-
-
-
-
-
-
- PPPPaaaaggggeeee 6666
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- any string ending in ``Callback'' - register Tcl code to be executed
- when something happens to the widget.
-
- For example,
-
- .form1.okLabel unmanageChild
-
- .form1.okButton activateCallback \
- {puts stdout "I was pushed into it..."}
-
- Unmanaging a widget removes it from the display, and from the geometry
- management of its parent. Managing it reverses this. The other methods
- are explained later.
-
-
- OOOOtttthhhheeeerrrr wwwwiiiiddddggggeeeetttt ccccoooommmmmmmmaaaannnnddddssss
- The root widget ``.'' has a number of commands unique to it. Generally,
- these are commands that use the application context (moat only uses one
- application context). These commands include
-
- addInput
- removeInput
- mainLoop
-
- Both Text and List have a large number of other commands due to the
- complexity of these widgets. Other widgets also have special methods.
- See the manual pages for further information.
-
-
- WWWWiiiiddddggggeeeetttt rrrreeeessssoooouuuurrrrcccceeeessss
- Each widget has a set of resources that can be set at creation time, set
- at a later time, or queried for their value. For example, an xmPushButton
- has a width and a height, a labelString that is the text that will show
- in it, a foreground and background colour, a fontList giving the set of
- fonts that will be used to draw the text, and so on.
-
- All resource names are prefixed by a minus `-' in Tcl programs, for
- consistency with the Tk widgets. On setting a value, all resources take
- the next word as value, and on getting a value the next word is the name
- of a variable to store the value in.
-
- On creation, the resource/value pairs come after the widget pathName, as
- in
-
- xmLabel .okLabel -labelType pixmap -labelPixmap xlogo32
-
- which sets the labelType to pixmap and the labelPixmap to xlogo32.
-
- Resources can be set at any time using the setValues method
-
- .text setValues -editMode editable -value "Some text"
-
-
-
-
- PPPPaaaaggggeeee 7777
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- which ensures that the text widget can be edited, and sets a value of
- "Some text".
-
- Resources can be obtained from the widget using the getValues method.
- For example
-
- .fileSelectionBox getValues \
- -dirSpec file_selected \
- -directory dir
-
- stores in the Tcl variable file_selected the filename that was entered,
- and in the Tcl variable dir the directory in which the file selection
- occurred.
-
- Each widget inherits resources from superclasses. For example, Label is a
- subclass of Primitive which in turn is a subclass of Core. From Core it
- inherits resources such as background, height and width. From Primitive
- it inherits resources such as foreground. It is neccessary to look at
- these superclasses. In addition, each class adds extra resources. For
- example, Label has the additional resources labelType, labelPixmap and
- labelString, among others.
-
- Resources are documented in the Tm man page for each widget. This
- documentation is weak.
-
- Resource names can be obtained from the Motif documentation for each
- widget. The Motif documentation for each widget has a set of tables
- headed ``Resource Set''. In the table of resources, the names of these
- are given prefixed by ``XmN'', such as XmNeditMode. Drop the prefix to
- get the Tcl resource name. Case is important here.
-
- Resource values can also be obtained from the Motif documentation. For
- each resource look at its type. Types such as Dimension and Position are
- numeric types, and along with int types need an integer value. In the
- Tcl program they are implemented as Tcl strings, as is everything. In
- fact, all resource values are Tcl strings. Pixmaps, for example, are the
- string name of a pixmap such as ``xlogo32''. Pixel is a color such as
- ``blue'', or a hexadecimal representation of the color. Types such as
- the arrowDirection of an ArrowButton form a discrete set with values
- listed as XmARROW_UP, XmARROW_DOWN, etc. For these types, drop the
- ``Xm'' and use the rest of the string as the value. On setting values,
- case is not important but on getting values the string will be lower case
- for these discrete types.
-
- So for example, a pushButton may have
-
- xmPushButton .btn -width 100
- .btn setValues -labelString "Push Me" -foreground red
- .btn getValues -background bg
- puts stdout "background colour is $bg"
-
-
-
-
-
- PPPPaaaaggggeeee 8888
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- CCCCaaaallllllllbbbbaaaacccckkkkssss
- When the user does things to a widget, it may cause the widget to take
- certain actions. For example, when a button is pressed it changes
- appearance to look pressed in. Some of these actions can have Tcl code
- attached to them, so that the Tcl code is evaluated when the action is
- performed. The Tcl code is attached to a ``callback'' by a widget
- command. For example, a pushButton has an activateCallback that is
- called when the user presses and releases the left mouse button inside
- the widget; it has an armCallback that is called when the user presses
- the mouse button; it has a disarmCallback that is called when the user
- releases the mouse button inside the widget.
-
- Tcl code is attached to a callback by giving it as the second argument to
- the appropriate widget methodod. For example,
-
- .btn armCallback {puts stdout "Stop squashing me!!!"}
- .btn disarmCallback {puts stdout "That's better!"}
-
- There are two ways of specifying the Tcl code: as above, giving all the
- code as a single word (including a list or a string), or as individual
- words:
-
- .btn armCallback puts stdout "Stop squashing me!!!"
-
- The names of the callbacks available for a particular widget are derived
- from the resource documentation for the Motif widget. Each callback ends
- with the string "Callback" in its name. Drop the "XmN" from the Motif
- description to gain the widget command. Callbacks are treated
- differently to other resources because the Xt toolkit treats them
- differently - the resource is not meant to be handled directly by any
- ordinary application.
-
-
- CCCCaaaallllllllbbbbaaaacccckkkk ssssuuuubbbbssssttttiiiittttuuuuttttiiiioooonnnnssss
- Motif supplies information to each callback function that is specific to
- the widget type. Generally this is not of much interest. However, for
- some widgets such as List this is used to supply important information,
- such as what item in the List was selected! To make this available to the
- Tcl callback function a pattern substitution mechanism may be used. Any
- ``%'' followed by a word will be treated as a pattern for potential
- substitution. For example, ``%item'' in a List will be replaced by the
- item selected, and ``%item_position'' will be replaced by its position in
- the list. An example list callback is
-
- .list singleSelectionCallback \
- {print_info %item %item_position}
-
- proc print_info {item position} {
- puts stdout "item was $item, at position $position"
- }
-
- The substitutions allowed may be found from the Motif documentation. In
-
-
-
- PPPPaaaaggggeeee 9999
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- the description of callback information one or more structures will be
- defined. The field names in these structures are the names used in ``%''
- substitutions. Not all of the possibilities are implemented yet. This is
- admittedly obscure and not easy to find, so the TclMotif documentation
- needs to fix this lack. If you feel upto reading C code instead, the upto
- date ``list'' is found in the file ``tmExpand.c''
-
- Every callback supports a substitution of ``%call_data''. This is a
- keyed list of all valid values in the callback structure. It is a list of
- two-element lists, where each two-element list consists of the name of
- the field followed by its value. For example, for an arrowButton it could
- be
- {
- {reason activate}
- {event event-12345}
- {click_count 1}
- }
- (the event value is a pointer to the Xlib data structure which may be
- used by tclMotif, but is not expected to be examined by a tcl program.)
-
- Some callback information is actually contained in the event that caused
- the callback to occur. The event may be obtained from the substitution
- %event. A tcl command ``xEvent'' may then be used to access the fields of
- the event. This command takes the event and an argument which is
- identical to the Tk % substitutions. For example, to extract the x
- coordinate from a motion event while in the callback, one could have
- $w setValues \
- -translations "<Motion>: action(trackit %event)"
-
- proc trackit {event} {
- set x [xEvent $event x]
- puts stdout $x
- }
-
-
- TTTTeeeexxxxtttt vvvveeeerrrriiiiffffyyyy ccccaaaallllllllbbbbaaaacccckkkkssss
- The Text widget allows special processing by the application of text
- entered. After a character has been typed, or text pasted in, initial
- processing by the Text widget determines what the user is entering. This
- text is then passed to special callback functions. These functions can
- make copies of the text, can alter it, or can set a flag to say do not
- display it. Simple uses for this are a password entry widget that reads
- the text but does not display it (or echoes `*' instead), or text
- formatting widgets.
-
- The callback mechanism for this is basically the same as for other
- callbacks, and similar sorts of substitutions are allowed. For example,
- the term %currInsert is replaced by the current insertion position. Other
- substitutions do not give a value, but rather give the name of a tcl
- variable. This allows the application to change the value as required.
- The tcl variable is in the context of the callback caller, so upvar
- should be used. For example, to turn off echoing of characters, the
-
-
-
- PPPPaaaaggggeeee 11110000
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- following should be done:
-
- .text modifyVerifyCallback {no_echo %doit}
-
- proc no_echo {doit} {
- upvar 1 $doit do_insert
-
- set do_insert false
- }
-
- (Actually, the tcl variable here is the global variable
- ``_Tm_Text_Doit''. For this reason, variables beginning with ``_Tm_'' are
- reserved for use by the TclMotif library.)
-
- Other substitutions that can be made in the modifyVerify callback are
- ``ptr'' and ``length''. ``ptr'' is the string that is being entered, and
- ``length'' is its length. These may be changed by the callback procedure.
- For example, to change all incoming text to uppercase,
-
- proc allcaps {ptr length} {
- upvar 1 $ptr p
- upvar 1 $length l
-
- if {$l == 0} return
- set upper [string toupper $p]
- set p $upper
- }
-
- .text modifyVerifyCallback {allcaps %ptr %length}
-
-
- DDDDiiiiaaaallllooooggggssss
- Selection Box has a number of component children, which may be managed or
- unmanaged by the application. If the SelectionBox was named .sel, these
- are
-
- .sel.Items
- .sel.ItemsList
- .sel.Selection
- .sel.Text
- .sel.Separator
- .sel.Apply
- .sel.Cancel
- .sel.Help
- .sel.OK
-
- The same applies to Message Box. These widgets are often managed or
- unmanaged to add or remove elements from a dialog. Each of these children
- is created with a method handler appropriate to the type of child.
- However, Motif documentation states that no assumptions should be made
- about this type, so you should check the type before using a widget-
- specific method. For example, the ItemsList in a SelectionBox is
-
-
-
- PPPPaaaaggggeeee 11111111
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- currently a Motif List. To set the selectedPosition, one can use a List
- method:
- xmSelectionBox .selBox managed
- selBox.ItemsList setValues \
- -items {a b c d} \
- -itemCount 4
-
- if {[.selBox.ItemsList class] == "XmList"} {
- .selBox.ItemsList selectPosition 4 false
- }
-
- Whatever the type, the set of methods of the tclMotif Core widget are
- supported. In particular, the methods ``manageChild'' and
- ``unmanageChild'' are available.
-
-
- AAAAccccttttiiiioooonnnnssss
- Actions may be added to a widget in a similar way to the C version. In
- that you define an action in a translation table which is set in the
- widget. You then have to register the action with the toolkit so that it
- is attached to a C function. In this binding, the tcl code is placed as
- the arguments to the action in the translation table. Registering the
- action links a generic action handler which in turn will handle the tcl
- code. Here is what it looks like to add an action to make an arrow turn
- left or right when `l' or `r' is pressed:
-
- xmArrowButton .arrow managed
-
- .arrow setValues -translations \
- "<Key>r: action(arrow_direction %w arrow_right) \n\
- <Key>l: action(\"arrow_direction %w arrow_left\")"
-
- proc arrow_direction {arrow direction} {
- puts stdout "Changing direction to $direction"
- $arrow setValues -arrowDirection $direction
- }
-
- The pattern ``%w'' is substituted for the name of the tcl widget. More
- substitutions may be added in later (eg for x, y).
-
-
-
-
- EEEExxxxaaaammmmpppplllleeeessss
- A number of examples are in the programs directory. Those with `DH' in
- them duplicate the examples in Dan Heller's ``Motif Programming Manual'',
- O'Reilly & Associates Inc. Those that are just numbered are undocumented
- test programs. They may not behave in a nice way, but that doesn't matter
- too much.
-
- The following example is in the programs directory as progEG. The
- typical structure of a Motif program is that the top-level object is a
-
-
-
- PPPPaaaaggggeeee 11112222
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- mainWindow. This holds a menu bar, and a container object such as a form
- or a rowColumn which in turn holds the rest of the application objects.
- So a mainWindow with a list and some buttons in a form would be created
- by
-
- xtAppInitialize -class Example
-
- xmMainWindow .main
- xmForm .main.form
- xmList .main.form.list
- xmPushButton .main.form.btn1
- xmPushButton .main.form.btn2
-
- The form acts as what is called the ``workWindow'' of the mainWindow.
- This resource would be set by
-
- .main setValues -workWindow .main.form
-
- Values would also be set into the list and buttons:
-
- .main.form.list setValues \
- -itemCount 3 \
- -items "one two three" \
- -selectionPolicy single_select
- .main.form.btn1 setValues -labelString Quit
- .main.form.btn2 setValues -labelString "Do nothing"
-
- Behaviour would be set by a callback function
-
- .main.form.btn1 activateCallback {exit 0}
- .main.form.list singleSelectionCallback {puts stdout "Selected %item"}
-
- Geometry would be set for the form, to put the objects in their correct
- relation to each other. Suppose this is the list on the left, with the
- two buttons one under the other on the right:
-
- .main.form.list setValues \
- -topAttachment attach_form \
- -leftAttachment attach_form \
- -bottomAttachment attach_form
- .main.form.btn1 setValues \
- -topAttachment attach_form \
- -leftAttachment attach_widget \
- -leftWidget .main.form.list
- .main.form.btn2 setValues \
- -topAttachment attach_widget \
- -topWidget .main.form.btn1 \
- -leftAttachment attach_widget \
- -leftWidget .main.form.list
-
- Finally, windows are created and the main event loop is entered:
-
-
-
-
- PPPPaaaaggggeeee 11113333
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- . realizeWidget
- . mainLoop
-
-
- MMMMeeeennnnuuuussss
- Motif supports three types of menus: pulldown menus, popup menus and
- option menus. It does so with a set of basic menu functions and an
- additional set of ``convenience'' functions. tclMotif supports the basic
- functions but not the convenience ones, since each author uses their own
- convenience functions and I am not convinced that the Motif ones are the
- ``best''.
-
- PPPPuuuullllllllddddoooowwwwnnnn mmmmeeeennnnuuuussss
- Pulldown menus need a MenuBar to hold the set of buttons. These buttons
- must be cascade buttons. From these are created PulldownMenu widgets,
- which are parented from the MenuBar. To establish the link between a
- cascade button and its corresponding pulldown menu, the resource
- subMenuId must be set on the cascade buton to be the pulldown menu. The
- pulldown menu can contain any menu widgets such as push buttons, with
- their associated callbacks.
-
- xmMenuBar .main.menuBar managed
- xmCascadeButton .main.menuBar.file managed \
- -labelString File \
- -mnemonic F
- xmCascadeButton .main.menuBar.edit managed \
- -labelString Edit \
- -mnemonic E
- xmCascadeButton .main.menuBar.help managed \
- -labelString Help \
- -mnemonic H
-
- # file pulldown
- xmPulldownMenu .main.menuBar.fileMenu
- xmPushButton .main.menuBar.fileMenu.new managed \
- -labelString "New..." \
- -mnemonic N
- xmPushButton .main.menuBar.fileMenu.quit managed \
- -labelString Quit \
- -mnemonic Q
- .main.menuBar.file setValues -subMenuId .main.menuBar.fileMenu
-
- PPPPooooppppuuuupppp mmmmeeeennnnuuuussss
- Popup menus are posted either from a keyboard accelerator or from a
- button 3 press over a widget. A popup menu is created by the function
- xmPopupMenu. A keyboard accelerator is set by the resource
- menuAccelerator for this widget. A button 3 press is easiest set up by
- adding an action to this button press that calls a menu popup function.
- This function should first call the popup menu widget method of
- menuPosition with one argument: the event that caused the popup. This
- event can be found by the action substitution %event. After this, the
- popup menu can be managed. Both methods are shown by this example:
-
-
-
- PPPPaaaaggggeeee 11114444
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- proc popIt {event} {
- .fred.menu menuPosition $event
- .fred.menu manageChild
- }
-
- xtAppInitialize -class Program
-
- xmLabel .fred managed -labelString "ctrl-p or Btn3Down popups from me"
- .fred setValues -translations \
- "<Btn3Down>: action(popIt %event)"
-
- xmPopupMenu .fred.menu -menuAccelerator "Ctrl <Key> p"
- xmPushButton .fred.menu.btn1 managed
- xmPushButton .fred.menu.btn2 managed
-
- . realizeWidget
-
- . mainLoop
-
- OOOOppppttttiiiioooonnnn mmmmeeeennnnuuuussss
- An option menu is made up of a PulldownMenu that is populated with
- buttons to give the alternative options. The option label is formed from
- an OptionMenu, with the labelString resource set to the label showing,
- and the subMenuId set to the PulldownMenu.
- # option menu
-
- xtAppInitialize -class Program
-
- xmRowColumn .rc managed
-
- xmPulldownMenu .rc.pulldown1
- xmPushButton .rc.pulldown1.options1 managed \
- -labelString "value 1"
-
- xmPushButton .rc.pulldown1.options2 managed \
- -labelString "value 2"
-
- xmOptionMenu .rc.option1 managed \
- -labelString "Option set" \
- -subMenuId .rc.pulldown1
-
- TTTTeeeeaaaarrrr----ooooffffffff mmmmeeeennnnuuuussss Pulldown and Popup menu panes can be made into tear-off
- menus by specifying the resource tearOffModel to have the value
- tear_off_enabled at the time of creation. They then show a tear-off
- button as a dotted line in the menu pane. Clicking on this with BSelect
- tears off the menu in place; dragging on this with BDrag will tear-off
- the menu and drag it elsewhere.
-
- When a menu is a tear-off menu, an additional button is created with
- separator-like behaviour. This button has a pathname made up of the
- rowcolumn's name followed by ``.TearOffControl''. For example,
- xmPulldownMenu .main.menuBar.fileMenu \
-
-
-
- PPPPaaaaggggeeee 11115555
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- -tearOffModel tear_off_enabled
-
- -foreground red -background black
-
-
- DDDDrrrraaaagggg aaaannnndddd DDDDrrrroooopppp
- Drag and drop was introduced into Motif 1.2. It is complicated. We shall
- first look at the drop side. A widget has to first register itself as a
- drop site, so that when an attempt is made to drop something on it, it
- will try to handle it. This registration is done by the widget method
- ``dropSiteRegister''. This registration must include tcl code to be
- executed when a drop is attempted, and this is done using the resource
- ``dropProc''. The first part of what makes D&D hard is that you have
- potentially two different applications attempting to communicate, one
- dropping and the other accepting the drop. A protocol is needed between
- these, so that they share a common language. This is done in registration
- by saying what types of protocol are used, and how many there are. This
- is done using X atoms, and the major ones are ``COMPOUND_TEXT'', ``TEXT''
- and ``STRING''. Thus registration by the drop site widget is done, for
- example, by
-
- .l dropSiteRegister \
- -dropProc {startDrop %dragContext} \
- -numImportTargets 1 \
- -importTargets COMPOUND_TEXT
-
- This allows `.l' to be used as a drop site, accepting ``COMPOUND_TEXT''
- only. Multiple types are allowed, using the Motif list structure of
- elements separated by commas as in "COMPOUND_TEXT, TEXT, STRING". When a
- drop occurs, the procedure ``startDrop'' is called, with one substituted
- parameter. This parameter is a ``dragContext'', which is a widget created
- to by Motif to handle the drag part of all this. You must include this
- parameter, or the next stage doesn't get off the ground.
-
- When a drag actually occurs, Motif creates a dragContext widget. A drag
- is started by holding down the middle button in a drag source, which is
- discussed later. The dragContext widget contains information about the
- drag source, which is to be matched up against where the drop occurs.
- When the drop occurs, by releasing the middle button, the tcl code
- registered as dropProc is executed. This should have the dragContext
- widget as parameter. This code may try to determine if the drop should
- go ahead, but more normally will just act as a channel through to the
- actual information transfer. Still here? Good. The dragProc doesn't
- actually do the information transfer, it just determines whether or not
- it is possible, and if it is, what protocols should be used, and how.
-
- The drop receiver may decide that it wants something encoded as TEXT,
- followed by something encoded as COMPOUND_TEXT, and then by something in
- STRING format (beats me why, though...). it signals this by a (Tcl) list
- of dropTransfer pairs, consisting of the protocol (as an X atom name) and
- the widget that is being dropped on. Huh? Why the widget that is being
- dropped on? Because when a drop on a widget takes place, this is actually
-
-
-
- PPPPaaaaggggeeee 11116666
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- dealt with by the dragContext widget, and this is about to hand the
- transfer over to a transferWidget. Yes, I know you are using Tcl because
- you couldn't handle triple indirections (or rather, don't want to!), but
- they occur anyway... So here is a simple dragProc:
-
- proc startDrop {dragContext} {
- $dragContext dropTransferStart \
- -dropTransfers {{COMPOUND_TEXT .l}} \
- -numDropTransfers 1 \
- -transferProc {doTransfer %closure {%value}}
- }
-
- The dragContext widget uses the command dropTransferStart to signal the
- beginning of the information transfer (it could also signal that the drop
- is to terminate, with no information transfer). It will accept one chunk
- of information in the COMPOUND_TEXT format, and pass this on to the .l
- widget. The information transfer is actually carried on by the Tcl
- procedure in the transferProc resource. The only formats currently
- accepted (because they are hard-coded into TclMotif) are COMPOUND_TEXT,
- TEXT and STRING.
-
- The transferProc resource is a function that is called when the drop
- receiver actually gets the information dropped on it. This should take at
- least two parameters. The %value is substituted for the actual
- information dropped on it, and %closure is the second element in the
- dropTransfer list which should be the widget the drop is happening on.
- (Why not let TclMotif determine this? I dunno. Consistency with Motif
- doco? Brain damage late at night?) Then the dropped on widget can take
- suitable action. This function resets the label to the text dropped on
- it:
-
- proc doTransfer {destination value} {
- $destination setValues -labelString $value
- }
-
- where destination is substituted by %closure and value by %value.
-
- So much for the drop site, receiving widget. On the other side, a widget
- has to prepared to act as a drag source and then to send information when
- dropped.
-
- A drag action is commenced (according to the Motif Style Guide) by
- dragging Button Two in the widget. To get this behaviour, the translation
- table for the widget has to have the Button2 action overriden. For
- example,
-
- xmScrollBar .sb managed \
- -translations "#override <Btn2Down>: action(startDrag %w)"
-
- This will call the application defined ``startDrag'' function with the
- widget as argument. The purpose of this function is to call the ``drag''
- method for that widget:
-
-
-
- PPPPaaaaggggeeee 11117777
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- proc startDrag {w} {
- $w dragStart \
- -exportTargets COMPOUND_TEXT \
- -numExportTargets 1 \
- -convertProc {dragConvertProc %w %type %value}
- }
-
- This states that it is only prepared to send a message of type
- ``COMPOUND_TEXT'', and when the toolkit requires the dropped value it
- will call the application defined function ``dragConvertProc'' with three
- parameters: the widget, the data-type that is to be transferred, and the
- data value to be transferred. These last two are modified by the
- function, so are actually variables in the parent's context. These have
- to be modified using upvar.
-
- For example, to send the value of a slider widget as COMPOUND_TEXT, the
- ``dragConvertProc'' would be:
-
- proc dragConvertProc {w type value} {
- upvar 1 $type t
- upvar 1 $value v
-
- $w getValues -value v
- set t COMPOUND_TEXT
- }
-
- tclMotif has builtin support for drops of three data types: TEXT,
- COMPOUND_TEXT and STRING. These form a large majority of the data types
- that may be dropped onto a widget. However, there may be others. To
- allow for this, tclMotif has a procedure Tm_InstallDropType that takes
- three parameters: a tcl interpreter, a string that will be used as an
- Atom to label a datatype, and a function of type
- char *(*) ()
- When a function is registered by using this command, it must be capable
- of transforming the datatype into a string, which it returns as value of
- the function. If this method is used, it should be added using the tcl
- extension techniques.
-
-
- SSSSeeeennnndddd
- Tk has a primitive called ``send''. In this, each interpreter has a name,
- and you can send tcl commands from one interpreter to another. When an
- interpreter receives a sent command it executes it, and returns any
- result back to the original interpreter. This mechanism is also available
- to TclMotif, so that Motif applications can set commands to other Motif
- applications, and also to and from Tk ones.
-
- If a TclMotif application succeeds in registering its name, from then on,
- it can send to another. For example,
-
- send interp2 {puts stdout "hello there"}
-
-
-
-
- PPPPaaaaggggeeee 11118888
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- instructs ``interp2'' to display a message.
-
- Similarly, once the ``send'' command has been registered, this
- application can be sent commands from other applications. The name of the
- interpreter is the ```title'' resource of the top-level widget `.'.
- Generally this will be the same as the application name, but may be
- changed in two ways: first the ``title'' resource may have been set
- explicitly. Secondly, ``send'' requires a unique name for the
- interpreter, so if an application is already running with that title, a
- ``#2'', or ``#3'', etc will be apended to the title until it is unique.
- This is not really satisfactory, but is the way that Tk does it.
-
-
- XXXXlllliiiibbbb DDDDrrrraaaawwwwiiiinnnngggg
- Motif only uses two widgets for Xlib style drawing: the DrawnButton and
- the DrawingArea. tclMotif allows drawing into these widgets, and does not
- allow drawing into other types of widget.
-
- At present, the drawing functions are limited to XDrawImageString, using
- the method ``drawImageString''. This requires use of a graphics context.
- A graphics context is first obtained by the call
- $w getGC -foreground fg -background
- Any widget can be used for this, but typically the drawing widget will be
- used.
-
- Given a graphics context, text can be drawn by
- $w drawImageString gc x y text
-
-
- MMMMooooddddaaaallll ddddiiiiaaaallllooooggggssss
- Dialogs in Motif are modeless by default. A dialog can be made modal by
- using the BulletinBoard resource dialogStyle which can be set to values
- such as ``dialog_full_application_modal''. This makes the dialog modal
- for the application, so that the dialog has to be completed before any
- interaction can occur with the rest of the application. Here
- ``completed'' means that the dialog must be unmanaged or destroyed.
-
- There is a serious difficulty in making dialogs modal: the modality is
- enforced by Xt, so that control must pass to Xt so that it can make the
- dialog modal. This usually means that no application code can follow
- setting the dialog resource, because control must pass back to the Xt
- event main loop.
-
- The problem here is that this is often what the programmer explicitly
- does _n_o_t want to do. A typical piece of code using modality is to ask a
- question such as ``remove file'' and use a modal dialog to wait for the
- answer and use it to determine what to do next. To allow this type of
- use, the application has to use its own event loop, and this is done by
- the `root' widget command ``processEvent'' which handles one event at a
- time.
-
- A modal piece of code sets up a loop around the ``processEvent'' method.
-
-
-
- PPPPaaaaggggeeee 11119999
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- This loop is controlled by a Boolean flag which is initially true. When
- the flag is set to false the loop terminates. The loop is typically set
- to false by pressing the various buttons in the dialog. For example
-
- proc ask {parent question} {
- global stillModal
- global answer
-
- xmQuestionDialog $parent.dialog managed \
- -messageString $question \
- -dialogStyle dialog_full_application_modal
-
- $parent.dialog okCallback {set stillModal 0; set answer 1}
- $parent.dialog cancelCallback {set stillModal 0; set answer 0}
-
- set stillModal 1
- while {$stillModal} {
- . processEvent
- }
- $parent.dialog destroyWidget
- }
-
- This can then be used in normal sequential code
-
- if {ask $w "remove $file"} {
- exec rm $file
- }
-
-
- AAAAddddddddiiiittttiiiioooonnnnaaaallll ttttoooopppplllleeeevvvveeeellll sssshhhheeeellllllllssss
- Additional toplevel shells may be created using the command
- topLevelShell. This shell may use any widget for its parent. In order
- to make this shell visible, it must be popped up.
- xtAppInitialize
- xmLabel .label managed \
- -labelString "label in app shell"
- topLevelShell .toplevel
- xmLabel .toplevel.label managed \
- -labelString "label in toplevel"
-
- Do _n_o_t atttempt to manage the toplevel shell - this will place it under
- the geometry control of its parent, so that when the parent resizes so
- will the shell! While this can produce some visually intriguing effects
- it is probably not what is desired, as well as breaking Xt rules.
-
-
- EEEExxxxtttteeeennnnddddiiiinnnngggg mmmmooooaaaatttt
- From Tcl 7.0 onwards, a standard method was set up to allow extensions to
- be made in a consistent manner. tclMotif follows this extension method.
- The method allows for open-ended extensions so that further extensions
- can be made to moat. You need access to the tcl library and also to the
- tclMotif library.
-
-
-
- PPPPaaaaggggeeee 22220000
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- Tcl expects a C function Tcl_AppInit() to be defined. This function
- should contain initialisation statements for each extension. In the case
- of tclMotif this function must contain a call to
- Tm_AppInit(interp)
- The prototype for this function is in tm.h, so this should be included as
- well.
-
- To perform your own extension, write your own Tcl_AppInit() function
- based on any existing ones as a template, including the above line and
- any similar code for the other extensions. Then compile and link this
- with the tcl and extension libraries.
-
- To add in additional widgets, see a later section for an easier way to do
- this.
-
-
- KKKKeeeeyyyybbbbooooaaaarrrrdddd ttttrrrraaaavvvveeeerrrrssssaaaallll
- Keyboard traversal is normally handled automatically by Motif. Sometimes
- it is necessary for the application to reset the keyboard focus to a
- particular widget or to the ``next'' widget in a set. The widgets are
- grouped in sets called ``tab groups'' by Motif. Tab group manipulation
- has not been added to tclMotif (at version 1.0).
-
- Keyboard focus may be set using the method ``processTraversal'' which
- takes a single argument. This may take values such as ``next'', ``up'',
- ``right'' to move to a suitable widget.
-
-
- AAAApppppppplllliiiiccccaaaattttiiiioooonnnn iiiiccccoooonnnnssss
- Toplevel widgets such as the application widget can have an icon attached
- to them so that it is shown when the application is iconified. This is
- done using the resource iconPixmap for the toplevel widget. The value of
- the resource is a filename containing the pixmap definition. This file
- may be found in a large set of directories such as the current directory
- or /usr/lib/X11/bitmaps. The full set - and the environment variables
- that control this set - is documented in the Motif call XmGetPixmap().
-
-
- AAAAuuuuttttoooommmmaaaatttteeeedddd tttteeeessssttttiiiinnnngggg
- Tcl uses an automated test system that can run regression tests on a
- system. it does so by ``sourcing'' a file containing a set of test
- procedures, including a procedure called ``test''. This takes 4
- arguments: the first is the name of the test, the second is a textual
- description of the test, the third is the code to execute to perform the
- test, and the last is the expected result. The ``test'' procedure runs
- the test and if the actual result differs from the expected one, an error
- message is printed.
-
- This mechanism is used well for the tcl core. It is also used for Tk, but
- with less success: while good for batch mode testing, it does not handle
- the interactive nature of GUI environments. To perform batch mode testing
- in such environments, one needs to be able to create input events to
-
-
-
- PPPPaaaaggggeeee 22221111
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- simulate an interactive user.
-
- One approach is to create raw X events and to feed them directly into the
- Xt event loop handler. This requires a very low-level knowledge of what
- is going on, and anyway does not reflect the object structure of the Xt
- toolkit. Each widget defines a set of ``actions'' that are intended to be
- the ``public'' interface of that widget. This is the hook that the
- tclMotif test procedures use to extend the tcl testing into this GUI
- environment.
-
- A command for any widget is ``callActionProc''. This takes an argument
- which is the name of the action for the widget. For example, a button has
- an Arm action, so this can be invoked by
-
- .btn callActionProc Arm()
-
- This will perform the visual behaviour for this action, and also call any
- callbacks associated with this action.
-
- This sends (by default) a ClientMessage event to the widget. Most widgets
- ignore the event, so this is sufficient. Some actions require event
- detail, though. For example, when a mouse button release occurs, the
- widget checks to see if the release occurred _i_n_s_i_d_e or _o_u_t_s_i_d_e the
- widget. It does this because if the event occurs inside, then the
- callbacks attached to the Activate() action are invoked, but otherwise
- they are not. To handle this, an event of type ButtonPress,
- ButtonRelease, KeyPress or KeyRelease can be prepared with some fields
- set.
-
- For tests, this means that you cannot just issue an Activate action. You
- do have to prepare an X button event to the extent of setting the x and y
- coordinates so that the internal Motif function can determine whether or
- not to invoke the callbacks. This looks like:
-
- .btn callActionProc Activate \
- -type ButtonPress \
- -x 0 -y 0
-
- to be within the widget, or
-
- .btn getValues -width w -height h
- set big_h [expr {2 * $h}]
- set big_w [expr {2 * $w}]
- .btn callActionProc Activate \
- -type ButtonPress \
- -x $big_w -y $big_h
-
- to be outside the widget.
-
-
- Some of the Text manipulation actions require a KeyPress event, such as
- ``self-insert()'', which inserts the character pressed. The character is
-
-
-
- PPPPaaaaggggeeee 22222222
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- actually encoded as a keycode, which is a hardware dependant code, too
- low-level for this binding. To prepare such an event, this toolkit uses
- _k_e_y_s_y_m_s which are abstractions for each type of key symbol. The
- alphanumerics have simple representations as themselves (`a', `A', `2',
- etc). Others have symbolic names (`space', `Tab', `BackSpace', etc).
- These are derived from the X Reference manual or in the file
- <X11/keysymdefs.h> by removing the prefix ``XK_''.
-
- For example, to insert the three characters `A a' into .text
-
- .text callActionProc self-insert() \
- -type KeyPress \
- -keysym A
- .text callActionProc self-insert() \
- -type KeyPress \
- -keysym space
- .text callActionProc self-insert() \
- -type KeyPress \
- -keysym a
-
- The set of actions that require this level of preparation of the X event
- is nowhere documented explicitly. You have to read between the lines of
- the Motif documentation, or guess at behaviour (or read Motif source
- code).
-
-
- AAAAddddddddiiiinnnngggg wwwwiiiiddddggggeeeettttssss
- [All the methods described in this section are new and a bit
- experimental. If there are any problems, please let me know.]
-
- tclMotif has support for the widget set supplied in the Motif toolkit.
- There are an increasing number of Motif-compatable widgets becoming
- available from third party sources. To add any of these involves adding
- appropriate C code to tclMotif.
-
- The file tmExtern.c contains some data structures that would have to be
- changed, and some skeleton code to assist in more complex tasks. You
- should make a copy of this file and either use it to replace the supplied
- tmExtern.c in each future release of tclMotif, or ensure that your
- version of this file is linked into each application before the supplied
- one.
-
- The array Tm_ExternCommands can be used to add additional commands to
- tclMotif. It is an array of type Tm_Cmd, which is a structure The
- elements of this structure are
- The string that is the widget creation name
- The C function that is used to actually create the widget
- The C function that is used to process the commands/methods issued
- to the new widget
- If there is nothing special about creating this widget, make the second
- element of this array Tm_AnyCmd. If the widget has no special methods of
- its own, make the third element of this array Tm_AnyWidgetCmd.
-
-
-
- PPPPaaaaggggeeee 22223333
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- For example,
- Tm_Cmd Tm_ExternCommands[] = {
- {"htmlWidget", Tm_AnyCmd, Tm_AnyWidgetCmd},
- {"myWidget", MyCreateCmd, MyWidgetCmd},
- {(char *) NULL, (int (*)()) NULL, (Tm_WidgetCmdProc) NULL}
- };
- adds in two more commands, ``htmlWidget'' and ``myWidget'', where the
- htmlWidget has no special creation requirements and no additional methods
- to the Core widget. On the other hand, myWidget has both special purpose
- creation requirements and additional methods, so needs custom creation
- and method functions. A skeleton for these two functions is supplied in
- the file tmExtern.c
-
- In addition the array Tm_ExternCommandToClass contains a mapping from the
- tcl widget creation command to the Xt class. This is used by Tm_AnyCmd
- and also by the String to WidgetClass converter. The first entry in this
- is the widget creation string, and the second entry is a _p_o_i_n_t_e_r to the
- Xt class. For example,
- Tm_CommandToClassType Tm_ExternCommandToClass[] = {
-
- /*
- * Example: the Mosaic html widget:
- */
- {"htmlWidget", &htmlWidgetClass},
-
- /*
- * array terminator - do not remove or
- * place anything after this
- */
- {NULL, NULL}
- };
-
- Additional widgets will have their own callbacks, and will probably have
- a callback structure associated to each. To allow `%' substitutions to be
- used in callback code for these widgets, the function
- Tm_ExternExpandPercent (in tmExtern.c) may be modified to add in such
- substitutions.
-
- You will finally need to make a change to the Imakefile in the src
- directory, by setting the variables EXTRA_WIDGETS_INCLUDE to point to the
- include directory and EXTRA_WIDGETS_LIB to link in the library containing
- these extra widgets. For example,
- EXTRA_WIDGETS_INCLUDE = /usr/local/include/html
- EXTRA_WIDGETS_LIB = -lhtmlw
-
- this may be simplified by using the command ``addwidget''. This takes the
- name of a widget and looks in the directory ``extern_widgets'' for a set
- of description files. For a widget ``foo'', these are:
-
- _f_o_o this contains lines specifying a pattern and a value. The
- patterns are
- command
-
-
-
- PPPPaaaaggggeeee 22224444
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- class
- create-function
- method-function
- include-file
- reason
- library
- include-dir
- The command is the tcl command to create the widget, the class is
- the Xt class of the widget, the create-function is the C command to
- create the widget, the method-function is the C command to handle
- methods, the include-file's are the any extra includes that need to
- be added to tmExtern.c, the reason's are any additional reasons that
- may be available for your widget, the library is the link library
- for the widgets, and the include-dir is any additional path for the
- compiler to locate include files.
-
- _f_o_o._i_n_i_t_i_a_l_i_s_e This contains the code to be inserted into the
- function Tm_ExternWidgetsInitialise. If this file does not exist,
- then no code will be inserted.
-
- _f_o_o._e_x_p_a_n_d This contains the code to be inserted into the function
- Tm_ExternExpandPercent. If this file does not exist, then no code
- will be inserted.
-
- _f_o_o._c_o_m_m_a_n_d_s This contains the function definitions for any non-
- standard widget creation and method handling that the extra widgets
- require.
-
- [If you make a description file for a widget, please send it to me for
- inclusion in the next release.]
-
-
- PPPPaaaatttttttteeeerrrrnnnnssss ffffoooorrrr ccccoooommmmmmmmaaaannnnddddssss
- Pathnames for commands can become very long for complex widget
- hierarchies. The ``unknown'' command has been augmented for tclMotif to
- allow patterns to be used as abbreviations for commands. The patterns are
- those accepted by the tcl command ``info''. The way that it is expected
- that this will be used in tclMotif is that a long path will be
- abbreviated by replacing an initial portion of the command by ``*'' or
- ``.*'' as in
- by
- (It is recommended that the `.' be used to start patterns in order that
- widgets are selected rather than other tcl commands.) Note that the
- pattern must uniquely match a command/widget name for the pattern match
- to be successful.
-
- The ``unknown'' procedure is augmented in the file init_tclMotif.tcl
- which is installed in the default X11 library directory (typically
- /usr/lib/X11). This is loaded by the tclMotif library unless the
- environment variable TM_LIBRARY is set to another directory, in which
- case the file init_tclMotif.tcl in that directory will be loaded instead.
-
-
-
-
- PPPPaaaaggggeeee 22225555
-
-
-
-
-
-
- ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm)))) ttttccccllllMMMMoooottttiiiiffff((((3333TTTTmmmm))))
-
-
-
- Any tcl program can rename any procedure, in particular the ``unknown''
- procedure. If this is done, then this pattern matching will cease to
- work. If you wish to prepend your own ``unknown'' procedure to this, it
- is recommended that you follow the ``stack'' structure used in
- init_tclMotif.tcl.
-
-
- UUUUIIIILLLL
- UIL (User Interface Language) is a declarative language for describing
- the widgets that make up an application. There is little to be gained by
- programming in UIL over programming in tclMotif. However, many interface
- builders have the option of outputting UIL code, and this can be used by
- tclMotif.
-
- A UIl file is translated into a UID file by the uil compiler. This can be
- loaded by
- The hierarchy can be closed by
- Only one hierarchy can be opened per program.
-
- A UIL widget tree can be attached to any widget by
- $w mrmFetchWidget uil-widget
-
- A traversal is made of the UIL widget tree, adding information that
- allows them to be used as tclMotif Core widgets. This means that you can
- use methods such as getValues, setValues, etc. Note that the top of the
- UIL tree is created unmanaged, so that you will will need to manage it
- yourself. For example:
- -topAttachment attach_form
-
- Callbacks in the UIL file should always be to the procedure ``tcl'' which
- takes a single string argument. This argument is the tcl command to be
- executed. For example, the UIL for an activateCallback may be
- XmNactivateCallback = procedure tcl("puts stdout goodbye");
- Widget names may be used in the callback procedures, but at present no %
- substitutions are supported (if you need them, let me know). Due to the
- impossibility of knowing exactly what the widget hierarchy will be when
- the UIL file is used, it is suggested that patterns described in the last
- section be used for widget names, as in
- XmNactivateCallback = procedure
- tcl("*btn setValues -labelString pushed");
-
-
- AAAAuuuutttthhhhoooorrrr
- Jan Newmarch, University of Canberra, PO Box 1, Belconnen, ACT 2616,
- Australia. Email: jan@ise.canberra.edu.au.
-
-
-
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 22226666
-
-
-
-